const { default: axios } = require("axios");
const User = require("../models/User");
const { appid, secret } = require("../config/weappConfig");
const validate = require("validate.js");

const { pick } = require("../util/propertyHelper");

exports.login = async function (code) {

  try {
    const res = await axios.get("https://api.weixin.qq.com/sns/jscode2session", {
      params: {
        appid,
        secret,
        js_code: code,
        grant_type: 'authorization_code',
      },
    });
    const { openid, session_key } = res.data;

    if (!openid) {
      throw new Error("Invalid code");
    }

    const user = await User.findOne({ where: { openid } });

    return user ? { user: pick(user.toJSON(), ["avatarUrl", "nickname", "openid", "id"]) } : { openid, session_key };

  } catch (err) {
    throw err;
  }

};

exports.getUserById = async function (id) {
  const result = await User.findByPk(id);
  if (result) {
    return result.toJSON();
  }
  throw new Error("User not found");
};

exports.createUser = async function (userObj) {
  userObj = pick(userObj, ["openid", "avatarUrl", "nickname"]);

  validate.validators.openidExits = async function (value) {
    const c = await User.findAndCountAll({ where: { openid: value } });

    if (c.count < 1) {
      return; // openid不存在， 验证通过
    }
    return "has been registered";
  };

  const rule = {
    //验证规则
    nickname: {
      presence: {
        allowEmpty: false,
      },
      type: "string",
      length: {
        minimum: 1,
        maximum: 10,
      },
    },

    avatarUrl: {
      type: "string",
    },
    openid: {
      presence: {
        allowEmpty: false,
      },
      type: "string",
      openidExits: true,
    },
  }

  await validate.async(userObj, rule); //验证
  const ins = await User.create(userObj);
  const jsonRes = ins.toJSON();
  return pick(jsonRes, ["avatarUrl", "nickname"]);
};

exports.updateUser = async function (id, userObj) {
  userObj = pick(userObj, ["avatarUrl", "nickname"]);

  validate.validators.userExits = async function (value) {
    const c = await User.findByPk(value);
    if (c) {
      return;
    }
    return "is not exist";
  };


  const rule = {
    //验证规则
    nickname: {
      presence: {
        allowEmpty: false,
      },
      type: "string",
      length: {
        minimum: 1,
        maximum: 10,
      },
    },

    avatarUrl: {
      type: "string",
    },
    id: {
      presence: {
        allowEmpty: false,
      },
      numericality: {
        onlyInteger: true,
        strict: false,
      },
      userExits: true, // 自定义验证规则 id必须存在
    },
  };

  await validate.async({ ...userObj, id }, rule); //验证

  return await User.update(userObj, {
    where: {
      id,
    },
  });

}

